﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GDoc.Domain;
using System.Security.Principal;
using System.Web;
using GDoc.Utils;
using GDoc.Domain.Services;
using GDoc.Data;

namespace GDoc.Web
{
    public class GDocPrincipal : IPrincipal
    {
        GDocIdentity identity;

        public GDocPrincipal(GDocIdentity identity)
        {
            this.identity = identity;
        }

        internal static GDocPrincipal BuildPrincipal(System.Web.HttpContextBase context)
        {
            if (context.User is GDocPrincipal)
                return context.User as GDocPrincipal;

            GDocIdentity identity = new GDocIdentity(context.User.Identity);

            GDocPrincipal principal = new GDocPrincipal(identity);

            context.User = principal;

            if ((principal.GIdentity.Account == null && CookiesUtil.Current[Constants.Cookie_CurrentAccount] != null) || 
                (principal.GIdentity.Account != null && principal.GIdentity.Account.ToString() != CookiesUtil.Current[Constants.Cookie_CurrentAccount]))
            {
                var account = new AccountService().GetById(Convert.ToInt64(CookiesUtil.Current[Constants.Cookie_CurrentAccount]));
                principal.GIdentity.Account = account;
            }


            return principal;
        }

        #region IPrincipal Members

        public IIdentity Identity
        {
            get { return identity; }
        }

        public GDocIdentity GIdentity
        {
            get { return identity; }
        }

        public bool IsInRole(string role)
        {
            return true;
        }

        #endregion

    }

    public class GDocIdentity : IIdentity
    {
        private IIdentity identity;

        public GDocIdentity(IIdentity identity)
        {
            this.identity = identity;

            if (identity.IsAuthenticated)
            {
                User = new UserService().GetByEmail(identity.Name);
            }
        }

        public string  Name
        {
            get
            {
                return identity.Name;
            }
        }

        public Domain.User User { get; set; }

        public Domain.Account Account
        {
            get
            {
                string accountCookieValue = CookiesUtil.Current[Constants.Cookie_CurrentAccount];
                
                if (!String.IsNullOrWhiteSpace(accountCookieValue))
                {
                    long accountId = Convert.ToInt64(accountCookieValue);

                    return RepositoryFactory.CreateAccountRepository().GetById(accountId);
                }

                return null;
            }
            set
            {
                CookiesUtil.Current[Constants.Cookie_CurrentAccount] = value == null ? string.Empty : value.Id.ToString();
            }
        }

        #region IIdentity Members

        public string AuthenticationType
        {
            get { return identity.AuthenticationType; }
        }

        public bool IsAuthenticated
        {
            get { return identity.IsAuthenticated; }
        }

        #endregion
    }
}
